using Sandia.MVCFramework.Common;
using Sandia.MVCFramework.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace Sandia.MVCFramework.ExportTools
{
    /// <summary>
    /// Abstract implementation of an IExporter for exporting
    /// to a named file
    /// </summary>
    public abstract class AbstractFileExporter: IExporter
    {
        /// <summary>
        /// Export the provided data to the named file 
        /// </summary>
        /// <param name="filename">File to export to</param>
        /// <param name="data">Data to export</param>
        /// <returns>True if export succeeded, false if not</returns>
        protected abstract bool exportData(string filename, IData data);

        /// <summary>
        /// set to true during disposal.
        /// </summary>
        private bool disposed = false;

        #region ISubscriber Members

        /// <summary>
        /// The list of IData types that this subscriber would like to subscribe
        /// to.
        /// </summary>
        public IList<Type> DesiredSubscriptions
        {
            get
            {
                List<Type> desiredSubscriptions = new List<Type>();
                desiredSubscriptions.Add(typeof(ExportContainer));
                return desiredSubscriptions;
            }
        }

        /// <summary>
        /// Method for receiving and handling published data
        /// </summary>
        /// <param name="dataPacket">
        /// The data packet that was published.
        /// </param>
        public void HandlePublishedData(DataPacket dataPacket)
        {
            try
            {
                if (dataPacket == null || dataPacket.Data == null) return;

                ExportContainer container = null;
                if (dataPacket.Data is ExportContainer)
                {
                    container = (ExportContainer)dataPacket.Data;                
                    if (!this.exportData(container.Filename, container.Payload))
                    {
                        // Generate a log entry
                        LoggingTools.SendToLog(
                            "Unable to export to " + container.Filename,
                            LoggingCategories.ERROR,
                            100);
                    }    
                }
            }
            catch (Exception e)
            {
                // Generate a log entry
                LoggingTools.SendToLog(
                    "Unable to export\n " + e.Message,
                    LoggingCategories.ERROR,
                    100);
            }
        }


        /// <summary>
        /// Whether or not this object has been disposed
        /// </summary>
        public bool IsDisposed
        {
            get { return disposed; }
        }

        /// <summary>
        /// To be called at the beginning of disposal
        /// </summary>
        public event EventHandler Disposed;

        #endregion

        #region IDisposable Members

        /// <summary>
        /// Set disposed to true and raise the event.
        /// </summary>
        public void Dispose()
        {
            disposed = true;
            if (Disposed != null) Disposed(this, new EventArgs());
        }

        #endregion
    }
}
